package com.cskaoyan.javase._2inner._1member._0introduction;

/**
 * 要想明确成员内部类的成员特点,需要明确以下两点:
 *      1.成员内部类可以近似的看成外围类的一个成员,这是因为:
 *          成员内部类对象当中,会持有外围类对象的引用,作为自身对象的成员变量.
 *          于是:
 *              要想得到成员内部类对象,必须先创建外围类对象,
 *              在外围类对象的基础上,才能去创建成员内部类对象
 *
 *     2.创建对象会触发类加载，即便是内部类也不例外。
 *          由1我们可以推导出，类加载的顺序也应该是先类加载外围类，再类加载成员内部类。
 *          所以，成员内部类没有静态声明。
 *          关于成员内部类中没有静态声明，至少可以有以下几个理由：
 *              a. 成员内部类被设计成依赖外围类而存在，如果一个成员内部类有了静态成员,
 *                  那么静态成员不依托于任何内部类实例，破坏了成员内部类依赖于外围类的设计。
 *              b.没有必要。静态成员的目的是脱离对象而使用一个变量或者方法，
 *                  完全可以将它们定义到外围类中，然后去使用。
 *              c.即便不从设计的角度考虑,那么单纯语法上,给成员内部类加上静态成员也是不合适的
 *                  比如如果有了静态成员,那就可以在静态成员中,创建自身对象
 *          总之,成员内部类的成员特点是: 没有static声明,在成员内部类的类加载过程中,不执行static相关的内容
 *
 * 成员内部类
 * 成员内部类是最普通的内部类，
 *      它定义在另一个类的成员位置，可以看成该类的一个成员。
 * 语法:
 * // 外围类
 * [访问权限修饰符] class EnclosedClazz{
 * // 成员内部类
 *   [访问权限修饰符] class InnerClazz{
 *  }
 * }
 * 成员内部类的自身特点:
 * 主要从以下几个角度分析：
 *      1.访问权限修饰符
 *          普通类的访问权限级别只有两个: public 和 默认访问权限
 *          成员内部类可以近似看成外围类的一个成员,访问级别四种皆有:
 *              public
 *              protected
 *              默认的权限
 *              private
 *          注: 一般来说,既然使用内部类,那需求就是隐藏这个内部类,访问权限给private.
 *
 *
 *      2.成员特点
 *          没有static声明,包括静态成员变量,静态成员方法,静态代码块.
 *          但是static修饰的全局常量,那些使用字面值赋值的全局常量
 *              由于不触发类初始化,是允许定义的.
 *
 *      3.继承和实现
 *          可以继承别的类,可以实现别的接口
 *          包括实现内部类,和内部接口
 *
 *
 * @since 16:58
 * @author wuguidong@cskaoyan.onaliyun.com
 */
public class Demo {
}

// 外围类
class EnclosedClazz {

    abstract class BaseA {
    }

    interface IA {
    }

    // 成员内部类
    class InnerClazz extends BaseA implements IA {
        int a;
        private int b = 10;
        static final int D = 100;
        static final String STRING = "123";

        // static final String STRING2 = new String("123");
        public void test() {
        }
        /*static int c = 20;
        static InnerClazz ic = new InnerClazz();
        static {}
        public static void testStatic(){}*/

    }
}

class A {
    static A a = new A();
}